﻿///<FileHeader>
///     <FileName>PropertyBehavior.cs</FileName>
///     <Author>Kiran Chand Palakkattiri</Author>
///     <Project>
///         <Name>Property Visibility Extensions for DSL</Name>
///         <Url>http://kiranchand.codeplex.com</Url>
///     </Project>
///     <CreationDate>August 02, 2009.</CreationDate>
///     <Contents>
///         <Content type="class" name="PropertyBehaviorAttribute"
///             comments="Attribute controls the visibilty behavior of
///             the configured domain properties."
///             baseclass="Attribute"/>
///     </Contents>
///     <Dependencies>
///         <Dependency type="reference" namespace="System" />
///         <Dependency type="reference" namespace="Microsoft.VisualStudio.Modeling"
///             assembly="Microsoft.VisualStudio.Modeling.Sdk" version="9.0.0.0" prerequisites="Visual Studio SDK 1.1" />
///     </Dependencies>
///     <Modifications/>
///     <Version>1.0.0.0</Version>
///</FileHeader>

using System;
using Microsoft.VisualStudio.Modeling;

namespace Kiranchand.Dsl.Extensions.PropertyVisibility
{
    /// <summary>
    /// Attribute controls the visibilty behavior of the configured domain properties.
    /// </summary>
    [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
    public sealed class PropertyBehaviorAttribute : Attribute
    {
        /// <summary>
        /// Gets mode of displaying the domain property on the property grid as DisplayMode.
        /// </summary>
        public DisplayMode DisplayMode { get; private set; }
        /// <summary>
        /// Gets the name (or domain property id without brackets)
        /// of the domain property (on which the visibility of the original property depends)
        /// as string
        /// </summary>
        public string DependantName { get; private set; }
        /// <summary>
        /// Gets the value of the dependent domain property as object.
        /// </summary>
        public object DependentValue { get; private set; }
        /// <summary>
        /// Gets the name (or domain property id without brackets) of the
        /// domain property to which the behavior is to be applied.
        /// </summary>
        public string PropertyName { get; private set; }

        /// <summary>
        /// Configures the visibility behavior of the domain property depending on the state (value) of another domain property
        /// </summary>
        /// <param name="sPropertyName">The name (or domain property Guid without brackets)
        /// of the domain property to which the behavior is to be applied. </param>
        /// <param name="displayMode">The mode of displaying the domain property on the property grid.</param>
        /// <param name="sDependantPropertyName">The name (or domain property Guid without brackets) of the depending domain property as string</param>
        /// <param name="oDependantValue">The state or value of the depending domain property
        /// for triggering the property behavior change.
        /// Rules - 
        /// 1. The the value must be only be the instance of system type (like integer, string, byte etc) litteral.
        /// 2. Variables other than constants are not allowed</param>
        
         /* Example Code for usage
          * [PropertyBehavior("1283fddb-106a-4a61-92eb-e649f5a99eef", DisplayMode.ReadOnly, "CommandField", "ReadOnly")]
          * [PropertyBehavior("StatusField", DisplayMode.Hidden, "adf1357d-2b3e-4c45-b66e-a34174dc57ce", "Hidden")]
          * [PropertyBehavior("1283fddb-106a-4a61-92eb-e649f5a99eef", DisplayMode.None, "adf1357d-2b3e-4c45-b66e-a34174dc57ce", "None")]
          * [PropertyBehavior("StatusField", DisplayMode.Editable, "CommandField", "Editable")]
          * public partial class Class
          * {
          * }
          */ 
         
        public PropertyBehaviorAttribute(string sPropertyName
            , DisplayMode displayMode
            , string sDependantPropertyName
            , object oDependantValue)
            : base()
        {
            // set the property name
            this.PropertyName = sPropertyName;
            // set the state
            this.DisplayMode = displayMode;
            // set the dependant
            this.DependantName = sDependantPropertyName;
            // set the dependant value
            this.DependentValue = oDependantValue;

        }

        /// <summary>
        /// Compares current behavior instance with the DomainPropertyInfo object
        /// </summary>
        /// <param name="oPropertyInfo">Instance of the DomainPropertyInfo</param>
        /// <returns>true if domain id or name is matching</returns>
        public bool CompareProperty(DomainPropertyInfo oPropertyInfo)
        {
            // first preference is for domain property id in comparison
            return this.PropertyName.Equals(oPropertyInfo.Id.ToString())
                || this.PropertyName.Equals(oPropertyInfo.Name);
        }
        /// <summary>
        /// Compares the current behavior instance with the name (or guid) and value of the domain property instance.
        /// </summary>
        /// <param name="oPropertyInfo">instance of the domain property</param>
        /// <param name="oSelectedElement">instance of the selected standardValueProvider</param>
        /// <returns></returns>
        public bool CompareDependency(DomainPropertyInfo oPropertyInfo, ModelElement oSelectedElement)
        {
            // first preference is for domain property id in comparison
            return (this.DependantName.Equals(oPropertyInfo.Id.ToString())
                || this.DependantName.Equals(oPropertyInfo.Name))
                    && oPropertyInfo.GetValue(oSelectedElement).Equals(this.DependentValue);
        }

    }
}
